package com.ubxtech.gateway.config;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.ubxtech.core.dto.LoginAppSecretConfig;
import com.ubxtech.core.exception.ErrorCodeCore;
import com.ubxtech.core.exception.RRException;
import com.ubxtech.core.utils.SignCheckUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author Victor.Xiao
 * @since 2023-12-21 10:42
 **/
@Slf4j
public class AppSecretConfigUtil {
    private AppSecretConfigUtil(){};

    /**
     * 授权的appId
     */
    private static Map<String, LoginAppSecretConfig> appSecretsMap;

    protected static void setAppSecretMap(Map<String, LoginAppSecretConfig> appSecretsMap) {
        AppSecretConfigUtil.appSecretsMap = appSecretsMap;
    }
    protected static void setAppSecretMap(List<LoginAppSecretConfig> appSecretConfigs) {
        if (CollectionUtil.isNotEmpty(appSecretConfigs)) {
            appSecretsMap = appSecretConfigs.stream().collect(Collectors.toMap(LoginAppSecretConfig::getAppId, a -> a, (k1, k2) -> k1));
        } else {
            appSecretsMap = new HashMap<>();
        }
    }

    public static Map<String, LoginAppSecretConfig> getAppSecretsMap() {
        return AppSecretConfigUtil.appSecretsMap;
    }

    public static AppSecretConfigUtil getInstance() {
        return AppSecretConfigUtilHolder.INSTANCE;
    }


    /**
     * 校验签名,返回空则认为校验失败
     * @author Victor.Xiao
     * @since 2021-12-15 20:01
     * @param appId appId
     * @param deviceId deviceId
     * @param sign sign
     * @return boolean
     */
    public static LoginAppSecretConfig checkSign(String appId, String deviceId,  String sign){

        //参数校验,如果没有则都是失败
        if (StrUtil.isBlank(appId) || CollectionUtil.isEmpty(AppSecretConfigUtil.getAppSecretsMap()) || AppSecretConfigUtil.getAppSecretsMap().get(appId) == null) {
            log.info("校验算法参数失败,{},{},{}",deviceId,appId,sign);
            throw new RRException(ErrorCodeCore.SIGN_APP_ID_NOT_EXISTS_ERROR);
        }
        LoginAppSecretConfig appConfig = AppSecretConfigUtil.getAppSecretsMap().get(appId);
        //不校验特定appId
        if (appConfig.getIgnoreFlag() != null && appConfig.getIgnoreFlag() == 1) {
            return appConfig;
        }
        String secretKey = appConfig.getSecretKey();
        //需要校验,则需要参数校验,如果没有则都是失败
        if (StrUtil.isBlank(sign)) {
            log.info("校验算法sign参数失败,{},{},{},{}",deviceId,appId,sign,secretKey);
            throw new RRException(ErrorCodeCore.SIGN_CONTENT_ERROR);
        }
        if (StrUtil.isBlank(secretKey)) {
            log.info("校验算法secretKey参数失败,{},{},{},{}",deviceId,appId,sign,secretKey);
            throw new RRException(ErrorCodeCore.SIGN_APP_ID_NOT_EXISTS_ERROR);
        }
        //默认忽略时间校验
        int ignoreTimeFlag = Optional.ofNullable(appConfig.getIgnoreTimeFlag()).orElse(0);
        boolean result = SignCheckUtil.checkSign(deviceId, secretKey, sign,ignoreTimeFlag,true);
        return result ? appConfig : null;
    }



    private static class AppSecretConfigUtilHolder {
        /**
         * 静态初始化器，由JVM来保证线程安全
         */
        private static final AppSecretConfigUtil INSTANCE = new AppSecretConfigUtil();
    }
}
